// Note selectivity of above compilers; under Metrowerks we
// assume the linker has been set to merge the whole app into
// one huge resource. Probably we should later include an
// explicit check for this, but right now I am using the
// CD ROM drive for music and can't look up the symbols. :-/
static OSErr MacLow_Init_LoadCODEs (void)
{
OSErr oe = noErr;
// This code attempts to load all the code segments low in the heap and
// lock them down. If we're not running under TPM, this should have been
// done already for us by the fact that all the code resources should be
// marked pre-load and lock in the resource map. If we are, we need to
// take extra steps.
//
// First, we check to see if we are running under TPM. Since the TPM
// opens an external, non-CODE resource file on top of the project file,
// where the CODE resources live, we can search the top resource file for
// CODEs to find out if the TPM has done this. And an easy way to do this
// is Count1Resources.
Boolean tpmRunning = false;
short code = Count1Resources ('CODE');
if (!(oe = ResError ( )) && !code)
{
// OK, now we know we are running under TPM.
// We need to get the "real" count of the CODE resources.
// We can do this by searching beyond the current file,
// which will catch the CODEs in the project.
tpmRunning = true;
code = CountResources ('CODE');
oe = ResError ( );
}
if (!oe)
{
// Now index all of
// them and get their IDs without loading them, reserve
// space for them at the bottom of the heap, load them,
// and lock them.
Handle codeH;
Size size;
short id;
ResType type;
Str255 name;
if (code)
{
Boolean oldResLoad = LMGetResLoad ( );
SetResLoad (false);
do
{
if (tpmRunning)
codeH = GetIndResource ('CODE', code);
else
codeH = Get1IndResource ('CODE', code);
oe = ResError ( ); if (oe) break;
GetResInfo (codeH, &id, &type, name);
oe = ResError ( ); if (oe) break;
// Skip the jump table and the startup code.
// This should be more intelligent about how
// various linkers handle their startup code.
// It's presently set up for THINK, but may
// work in other cases.
if (id != 0 && id != 1)
{
size = GetResourceSizeOnDisk (codeH);
oe = ResError ( ); if (oe) break;
ReserveMem (size);
oe = MemError ( ); if (oe) break;
LoadResource (codeH);
oe = ResError ( ); if (oe) break;
HLock (codeH);
oe = MemError ( ); if (oe) break;
HNoPurge (codeH); // just for paranoia
oe = MemError ( ); if (oe) break;
}
}
while (--code);
SetResLoad (oldResLoad);
}
}
return (oe);
}
#endif
--
Pete Gontier // CTO, Integer Poet Software // gurgle@dnai.com
"The need to be (or appear to be) sophisticated pervades the very
atmosphere in which we, the Magazine Reading Class, move."
-- Ellis Weiner, Spy Magazine, 9/94
+++++++++++++++++++++++++++
>From paitech@hntp2.hinet.net (paitech)
Date: 10 Sep 1994 18:51:43 GMT
Organization: NCTU News Server, HiNet
Pete Gontier (gurgle@dnai.com) wrote:
: much getting away with it, and (2) it provides you with code you might
: want to use instead of marking your segments pre-loaded. That way, for the
: PPC version, you can simply omit the code.
But you still have to preload the main segment (i.e. CODE 1), right?
Hao-yang Wang
Pai Technology, Inc.
Taipei
+++++++++++++++++++++++++++
>From gurgle@dnai.com (Pete Gontier)
Date: Sat, 10 Sep 1994 18:14:54 -0800
Organization: Integer Poet Software
In article <34sv7v$8hr@serv.hinet.net>, paitech@hntp2.hinet.net (paitech) wrote:
> Pete Gontier (gurgle@dnai.com) wrote:
> : much getting away with it, and (2) it provides you with code you might
> : want to use instead of marking your segments pre-loaded. That way, for the
> : PPC version, you can simply omit the code.
>
> But you still have to preload the main segment (i.e. CODE 1), right?
I'm not terribly familiar with the PPC code model, so it's possible you
might have to do this, but I think it's always a pretty safe assumption
that if your code is running, CODE 1 loaded successfully. :-)
--
Pete Gontier // CTO, Integer Poet Software // gurgle@dnai.com
"The need to be (or appear to be) sophisticated pervades the very
atmosphere in which we, the Magazine Reading Class, move."
-- Ellis Weiner, Spy Magazine, 9/94
+++++++++++++++++++++++++++
>From paitech@hntp2.hinet.net (paitech)
Date: 11 Sep 1994 08:50:52 GMT
Organization: NCTU News Server, HiNet
Pete Gontier (gurgle@dnai.com) wrote:
: > But you still have to preload the main segment (i.e. CODE 1), right?
: I'm not terribly familiar with the PPC code model, so it's possible you
: might have to do this, but I think it's always a pretty safe assumption
: that if your code is running, CODE 1 loaded successfully. :-)
Let me make my question clearer:
You suggested that instead of marking the resident segments PRELOADED, we can
also load them manually at runtime. This is a good idea (It cannot be bad
because MacApp has done it in a similar way since 1.0.), but when your code is
executed (under 68k), the main segment is already loaded (into the middle of
the heap?) and it is already too late to reallocate the main segment.
So the main segment should still be marked as PRELOADED and we still have to
release it under PPC, right?
Hao-yang Wang
Pai Technology, Inc.
Taipei
+++++++++++++++++++++++++++
>From h+@nada.kth.se (Jon W{tte)
Date: Sun, 11 Sep 1994 19:47:54 +0200
Organization: Royal Institute of Something or other
In article <34ugdc$pqk@serv.hinet.net>,
paitech@hntp2.hinet.net (paitech) wrote:
>You suggested that instead of marking the resident segments PRELOADED, we can
>also load them manually at runtime. This is a good idea (It cannot be bad
>because MacApp has done it in a similar way since 1.0.), but when your code is
>executed (under 68k), the main segment is already loaded (into the middle of
>the heap?) and it is already too late to reallocate the main segment.
>So the main segment should still be marked as PRELOADED and we still have to
>release it under PPC, right?
No.
The Segment Loader loads CODE 0 and whatever's referenced by
the first jump table entry for you. At this time, the heap is
really small (MaxApplZone() hasn't been called) and there's
nothing else in it (what would it be? No memory allocation's
been done) so that CODE resource is loaded snugly in the heap;
no fragmentation.
If your main() function is not in the same segment as the
startup loader bootstrap (runtime library) you'll have a third
CODE resource load before you get to the start of main, and
still MaxApplZone() isn't called and no non-permanent memory is
allocated to there's no chance of fragmentation.
So, don't mark CODE 0 or CODE 1 (or ANY CODE) preloaded for a
fat binary.
OR special-case for PPC to get all CODE resources and release
them :-) :-) :-)
Cheers,
/ h+
--
Jon W‰tte (h+@nada.kth.se), Hagagatan 1, 113 48 Stockholm, Sweden
Nothing crashes like a Macintosh.
-- Guy Kawasaki
+++++++++++++++++++++++++++
>From paitech@hntp2.hinet.net (paitech)
Date: 12 Sep 1994 13:55:17 GMT
Organization: NCTU News Server, HiNet
Jon W{tte (h+@nada.kth.se) wrote:
: The Segment Loader loads CODE 0 and whatever's referenced by
: the first jump table entry for you. At this time, the heap is
: really small (MaxApplZone() hasn't been called) and there's
: nothing else in it (what would it be? No memory allocation's
: been done) so that CODE resource is loaded snugly in the heap;
: no fragmentation.
There is still fragmentation. You can break into Macsbug and check for it
yourself. It is not caused by other memory allocations, but by the MiveHHi()
call (made by the Segment Loader). However, the heap is really small at this
time, so the memory loss caused by this fragmentation may be no more than
several kilo bytes. We may just ignore this fragmentation.
: So, don't mark CODE 0 or CODE 1 (or ANY CODE) preloaded for a
: fat binary.
In CodeWarrior, this is easy. In MPW, you may need to write a rez script for
this post-link process. I don't know an easy way to clear the preloaded bit
under the Symantec environment.
Another related problem is the SIZE resource. On one hand, under the PPC
runtime environment the code does not take up the application heap, on the
other hand, the PPC stack size is usually larger than the 68k one. Anyway,
if the memory requirements for PPC and 68k are different, how can one SIZE
fit for both?
I am writing a fat 'appe', and the SIZE resource becomes a problem, because
1) users cannot change the memory partition in the "Get Info..." Finder
dialog for the 'appe';
2) the 'appe' will always resident in background and take up memory, so I
cannot throw away hundreds of kilo bytes here and there, as I used to do.
Maybe I should put an INIT resource into the the appe file, to adjust the
SIZE resource dynamically at the startup time, according to the current
machine architecture. But I think I have used up all my quota on dirty
tricks this year. :-)
Hao-yang Wang
Pai Technology, Inc.
Taipei
+++++++++++++++++++++++++++
>From gurgle@dnai.com (Pete Gontier)
Date: Mon, 12 Sep 1994 10:22:25 -0800
Organization: Integer Poet Software
In article <351mk5$sus@serv.hinet.net>, paitech@hntp2.hinet.net (paitech) wrote:
> There is still fragmentation. You can break into Macsbug and check for it
> yourself. It is not caused by other memory allocations, but by the MiveHHi()
> call (made by the Segment Loader). However, the heap is really small at this
> time, so the memory loss caused by this fragmentation may be no more than
> several kilo bytes. We may just ignore this fragmentation.
Ah. After some twiddling of my own current project, I see what you are
getting at. For various technical reasons, I was not running into the
problem. My code was only intended to get around the tricky resource fork
problem in the TPM. The real solution for 68K is to have all your code
segments locked and pre-loaded, which is fine, because my TPM solution
knows whether it's running under TPM and bails out if not.
But you still have a problem -- how to make the 68K code all load and stay
loaded without fragmenting the heap while at the same time *not* loading
when the PPC code runs. Making sure the 68K code does not waste RAM while
the PPC code is running not only requires you to get and release the CODE
resources but *also* costs you startup time, because those resources take
some non-zero time to be read in from the disk, even when running under
PPC.
As you say, though, the heap is really small at that time, and you might
just want to sacrifice the wasted space to the gods of convenience.
Anyway, I will think about this some more as a mental background process,
for whatever that's worth. :-)
--
Pete Gontier // CTO, Integer Poet Software // gurgle@dnai.com
"The need to be (or appear to be) sophisticated pervades the very
atmosphere in which we, the Magazine Reading Class, move."
-- Ellis Weiner, Spy Magazine, 9/94
+++++++++++++++++++++++++++
>From wdh@fresh.com (Bill Hofmann)
Date: Mon, 12 Sep 1994 17:36:24 GMT
Organization: Fresh Software
In article <34ugdc$pqk@serv.hinet.net>, paitech@hntp2.hinet.net (paitech) wrote:
> Let me make my question clearer:
>
> You suggested that instead of marking the resident segments PRELOADED, we can
> also load them manually at runtime. This is a good idea (It cannot be bad
> because MacApp has done it in a similar way since 1.0.), but when your code is
> executed (under 68k), the main segment is already loaded (into the middle of
> the heap?) and it is already too late to reallocate the main segment.
>
> So the main segment should still be marked as PRELOADED and we still have to
> release it under PPC, right?
>
> Hao-yang Wang
> Pai Technology, Inc.
> Taipei
No. The system loads CODE 1 (and CODE 0) itself in the process of launching your application if it's a 68k app. You really don't have to mark any resources preload except your error reporting resources (DLOG or ALRT, DITL, STRs or STR#s, etc). You don't have to mark CODE 1 preload.
--
Bill Hofmann wdh@fresh.com
Fresh Software and Instructional Design voice: +1 510 524 0852
1640 San Pablo Ave #C Berkeley CA 94702 USA fax: +1 510 524 0853
+++++++++++++++++++++++++++
>From gurgle@dnai.com (Pete Gontier)
Date: Mon, 12 Sep 1994 12:20:17 -0800
Organization: Integer Poet Software
In article <wdh-1209941036240001@wdh.slip.netcom.com>, wdh@fresh.com (Bill
Hofmann) wrote:
> You really don't have to mark any resources
> preload except your error reporting resources
> (DLOG or ALRT, DITL, STRs or STR#s, etc).
I think perhaps you are missing the idea that he *wants* to pre-load all
his code resources so that he doesn't have to worry about the memory
management issues associated with code segments loading and unloading via
Segment Loader and the jump table. It's not that he thinks he must; he's
choosing to do so in order to make his memory management simpler. This is
not optimal in terms of memory usage, but code takes up a surprisingly
small amount of relative space in some apps, and making sure it's all
always loaded can simplify QA a lot.
--
Pete Gontier // CTO, Integer Poet Software // gurgle@dnai.com
"The need to be (or appear to be) sophisticated pervades the very
atmosphere in which we, the Magazine Reading Class, move."
-- Ellis Weiner, Spy Magazine, 9/94
+++++++++++++++++++++++++++
>From gurgle@dnai.com (Pete Gontier)
Date: Mon, 12 Sep 1994 12:25:50 -0800
Organization: Integer Poet Software
In article <wdh-1209941036240001@wdh.slip.netcom.com>, wdh@fresh.com (Bill
Hofmann) wrote:
> The system loads CODE 1 (and CODE 0) itself in the process of
> launching your application if it's a 68k app... You don't have to mark
> CODE 1 preload.
I forgot to note something else:
Most development systems automatically mark CODE 1 as pre-loaded. This has
the effect of forcing the segment into the lowest possible position in the
heap as soon as the app's resource file is opened. (Ordinarily this is a
good thing, because CODE 1 tends to do things like patch ExitToShell, and
you don't want it moving around.) It may be that under some systems the
process manager does the right thing to make sure this happens anyway, but
since most development systems mark CODE 1 as pre-loaded regardless, it's
still a good idea to figure out how to deal with it under PowerPC in a fat
binary situation.
--
Pete Gontier // CTO, Integer Poet Software // gurgle@dnai.com
"The need to be (or appear to be) sophisticated pervades the very
atmosphere in which we, the Magazine Reading Class, move."
In article <wdh-1209941036240001@wdh.slip.netcom.com>, wdh@fresh.com (Bill
Hofmann) wrote:
> The system loads CODE 1 (and CODE 0) itself in the process of
> launching your application if it's a 68k app... You don't have to mark
> CODE 1 preload.
I forgot to note s
+++++++++++++++++++++++++++
>From wdh@fresh.com (Bill Hofmann)
Date: Thu, 15 Sep 1994 17:18:00 GMT
Organization: Fresh Software
In article <gurgle-1209941220170001@dynamic-210.dnai.com>, gurgle@dnai.com
(Pete Gontier) wrote:
> I think perhaps you are missing the idea that he *wants* to pre-load all
> his code resources so that he doesn't have to worry about the memory
> management issues associated with code segments loading and unloading via
> Segment Loader and the jump table. It's not that he thinks he must....
Well, no, I didn't miss it, but his question seemed to indicate that he thought that he *had* to. If he's still listening, I'd suggest something like this:
#ifndef powerc
<preload code resources>
#endif
That'll do it. But preloading and other memory management things should be done at the end of the development process, when you can spend a lot of time staring at Macsbug heap displays. I hold that nowadays it's much less of an issue than it was 8 years ago.
--
Bill Hofmann wdh@fresh.com
Fresh Software and Instructional Design voice: +1 510 524 0852
1640 San Pablo Ave #C Berkeley CA 94702 USA fax: +1 510 524 0853
+++++++++++++++++++++++++++
>From gurgle@dnai.com (Pete Gontier)
Date: Fri, 16 Sep 1994 10:25:41 -0800
Organization: Integer Poet Software
In article <wdh-1509941018000001@wdh.slip.netcom.com>, wdh@fresh.com (Bill
Hofmann) wrote:
> #ifndef powerc
> <preload code resources>
> #endif
He can do that, but if he does, CODE 1 and the segment which contains
'main' and the segment which contains the code which loads the rest of the
segments may already have been loaded in a sub-optimal place. (In fact,
they are almost guranteed to have been.) He wants a solution which (a)
doesn't require him to worry about what code goes where, and (b) doesn't
create any heap islands. The traditional solution of marking all the code
segments pre-loaded and locked doesn't, of course, work under PPC in a fat
binary because the code segments should *never* be loaded in that case.
That's why this is such a vexing problem.
> But preloading and other memory management things should be done at the end
> of the development process, when you can spend a lot of time...
That's precisely when when you *cannot* spend a lot of time! :-) Anyway, I
think if you are going to adopt the policy of not messing with the segment
loader at all, it's prudent to make that part of the program work right up
front. You should see the colors my face turns when I'm trying to debug
one crash and another crash happens because of something like a segment
loader error. :-)
> I hold that nowadays it's much less of an issue than it was 8 years ago.
Right. That's why he wants to dispense with that pesky Segment Loader.
--
Pete Gontier // CTO, Integer Poet Software // gurgle@dnai.com
"I saw John Norstad with Elvis! And they were varnishing waffles!"